

#include <cassert>
#include <iostream>
#include <string>
#include "MathAdapter.h"
using namespace std;

void DebugAssertIf(bool exp) {
	if (exp) {
		__debugbreak();
	}
}

void AssertIf(bool exp) {
	if (exp) {
		__debugbreak();
	}
}

void Assert(bool value) {
	if (!value) {
		__debugbreak();
	}
}

void DebugAssert(bool value) {
	if (!value) {
		__debugbreak();
	}
}


float Abs(float v)
{
	return v < 0.0F ? -v : v;
}


double Abs(double v)
{
	return v < 0.0 ? -v : v;
}

int Abs(int v)
{
	return v < 0 ? -v : v;
}

int RoundfToInt(float f)
{
	return FloorfToInt(f + 0.5F);
}

UInt32 RoundfToIntPos(float f)
{
	return FloorfToIntPos(f + 0.5F);
}

float Roundf(float f)
{
	return Floorf(f + 0.5F);
}


float Floorf(float f)
{
	// Use std::floor().
	// We are interested in reliable functions that do not lose precision.
	// Casting to int and back to float would not be helpful.
	return floor(f);
}

double Floord(double f)
{
	// Use std::floor().
	// We are interested in reliable functions that do not lose precision.
	// Casting to int and back to float would not be helpful.
	return floor(f);
}

float FloatMin(float a, float b)
{
	return std::min(a, b);
}

float FloatMax(float a, float b)
{
	return std::max(a, b);
}

float SqrtImpl(float f)
{
	return sqrtf(f);
}


float Sin(float f)
{
	return sinf(f);
}

float Pow(float f, float f2)
{
	return powf(f, f2);
}

float Cos(float f)
{
	return cosf(f);
}


float Sign(float f)
{
	if (f < 0.0F)
		return -1.0F;
	else
		return 1.0;
}

float FastSqrt(float value)
{
	return sqrtf(value);
}



float FastInvSqrt(float f)
{
	// The Newton iteration trick used in FastestInvSqrt is a bit faster on
	// Pentium4 / Windows, but lower precision. Doing two iterations is precise enough,
	// but actually a bit slower.
	if (fabs(f) == 0.0F)
		return f;
	return 1.0F / sqrtf(f);
}

float FastestInvSqrt(float f)
{
	union
	{
		float f;
		int i;
	} u;
	float fhalf = 0.5f * f;
	u.f = f;
	int i = u.i;
	i = 0x5f3759df - (i >> 1);
	u.i = i;
	f = u.f;
	f = f * (1.5f - fhalf * f * f);
	// f = f*(1.5f - fhalf*f*f); // uncommenting this would be two iterations
	return f;
}

bool IsNAN(float value)
{
	return _isnan(value) != 0;
}

bool IsNAN(double value)
{
	return _isnan(value) != 0;
}

int FloorfToInt(float f)
{
	DebugAssertIf(f < INT_MIN || f > INT_MAX);
	return f >= 0 ? (int)f : (int)(f - kBiggestFloatSmallerThanOne);
}

UInt32 FloorfToIntPos(float f)
{
	DebugAssertIf(f < 0 || f > UINT_MAX);
	return (UInt32)f;
}

double Ceild(double f)
{
	// Use std::ceil().
	// We are interested in reliable functions that do not lose precision.
	// Casting to int and back to float would not be helpful.
	return ceil(f);
}


int CeilfToInt(float f)
{
	DebugAssertIf(f < INT_MIN || f > INT_MAX);
	return f >= 0 ? (int)(f + kBiggestFloatSmallerThanOne) : (int)(f);
}

UInt32 CeilfToIntPos(float f)
{
	DebugAssertIf(f < 0 || f > UINT_MAX);
	return (UInt32)(f + kBiggestFloatSmallerThanOne);
}

float Ceilf(float f)
{
	// Use std::ceil().
	// We are interested in reliable functions that do not lose precision.
	// Casting to int and back to float would not be helpful.
	return ceil(f);
}

int CompareFloatRobustSignUtility(float A)
{
	// The sign bit of a number is the high bit.
	union
	{
		float f;
		int i;
	} u;
	u.f = A;
	return (u.i) & 0x80000000;
}

bool CompareFloatRobust(float f0, float f1, int maxUlps)
{
	// After adjusting floats so their representations are lexicographically
	// ordered as twos-complement integers a very small positive number
	// will compare as 'close' to a very small negative number. If this is
	// not desireable, and if you are on a platform that supports
	// subnormals (which is the only place the problem can show up) then
	// you need this check.
	// The check for A == B is because zero and negative zero have different
	// signs but are equal to each other.
	if (CompareFloatRobustSignUtility(f0) != CompareFloatRobustSignUtility(f1))
		return f0 == f1;

	union
	{
		float f;
		int i;
	} u0, u1;
	u0.f = f0;
	u1.f = f1;
	int aInt = u0.i;
	// Make aInt lexicographically ordered as a twos-complement int
	if (aInt < 0)
		aInt = 0x80000000 - aInt;
	// Make bInt lexicographically ordered as a twos-complement int
	int bInt = u1.i;
	if (bInt < 0)
		bInt = 0x80000000 - bInt;

	// Now we can compare aInt and bInt to find out how far apart A and B
	// are.
	int intDiff = Abs(aInt - bInt);
	if (intDiff <= maxUlps)
		return true;
	return false;
}

